package models

import (
	"encoding/json"
	"github.com/astaxie/beego/orm"
)

type AuthRule struct {
	Id      int64  `json:"id"`
	Url     string `json:"uid"`
	GroupId int64  `json:"group_id"`
	Auth    int    `json:"auth"`
	Status  int8   `json:"status"`
}

type ResutlRule struct {
	Id       int64         `json:"id"`
	Title    string        `json:"title"`
	Key      string        `json:"key"`
	Expand   bool          `json:"expand"`
	Checked  bool          `json:"checked"`
	Children []*ResutlRule `json:"children"`
}

type GroupIdParam struct {
	GroupId int64 `json:"group_id"`
}

type AuthSaveParam struct {
	Id          int64    `json:"id"`
	Name        string   `json:"name"`
	Description string   `json:"description"`
	Rules       []string `json:"rules"`
}

//登陆获取权限
func GetAuthByLogin(gid string) (arr []string, err error) {
	var ids []int64
	_ = json.Unmarshal([]byte(gid), &ids)
	var maps []orm.Params
	_, err = orm.NewOrm().QueryTable("tp_auth_rule").Filter("group_id__in", ids).Distinct().Values(&maps, "url")
	if err == nil {
		for _, item := range maps {
			arr = append(arr, item["Url"].(string))
		}
	}
	return arr, err
}

//访问权限数组  access
func GetAuthByGroupId(id int64) (arr []string, err error) {
	var maps []orm.Params
	query := orm.NewOrm().QueryTable("tp_auth_rule")
	_, err = query.Filter("GroupId", id).Values(&maps, "Url")
	if err == nil {
		for _, item := range maps {
			arr = append(arr, item["Url"].(string))
		}
	}
	return arr, err
}

//编辑权限组
func AuthSave(params *AuthSaveParam) error {
	rules := params.Rules
	o := orm.NewOrm()
	err := o.Begin()

	if params.Id == 0 { //新增
		group := AuthGroup{
			Name:        params.Name,
			Description: params.Description,
			Status:      1,
		}
		id, err := o.Insert(&group)
		if err == nil {
			if len(rules) > 0 {
				data := []*AuthRule{}
				for _, item := range rules {
					tmp := AuthRule{
						Url:     item,
						GroupId: id,
						Auth:    0,
						Status:  1,
					}
					data = append(data, &tmp)
				}
				_, err = o.InsertMulti(1, data)
			}

		}
		if err == nil {
			err = o.Commit()
		} else {
			err = o.Rollback()
		}
	} else { //编辑
		// 更新 AuthGroup
		group := AuthGroup{
			Id:          params.Id,
			Name:        params.Name,
			Description: params.Description,
		}
		_, err = o.Update(&group, "id", "name", "description")
		if err == nil {
			if len(rules) > 0 {
				lists := []*AuthRule{}
				num, err := o.QueryTable("tp_auth_rule").All(&lists)
				if err == nil && num > 0 {
					//处理 已存在  新增 舍弃 数据
					needDel := []int64{}
					needAdd := []*AuthRule{}
					has := []*AuthRule{}
					for _, item := range rules {
						ex := false
						for _, it := range lists {
							if it.Url == item {
								ex = true
								has = append(has, it)
							}
						}
						if ex == false {
							tmp := AuthRule{
								Url:     item,
								GroupId: params.Id,
								Auth:    0,
								Status:  1,
							}
							needAdd = append(needAdd, &tmp)
						}
					}

					for _, item := range lists {
						ex := false
						for _, it := range has {
							if item.Id == it.Id {
								ex = true
							}
						}
						if ex == false {
							needDel = append(needDel, item.Id)
						}
					}

					if len(needAdd) > 0 {
						_, err = o.InsertMulti(1, needAdd)
						if err != nil {
							err = o.Rollback()
							return err
						}
					}

					if len(needDel) > 0 {
						_, err = o.QueryTable("tp_auth_rule").Filter("id__in", needDel).Delete()
						if err != nil {
							err = o.Rollback()
							return err
						}
					}
				}
			}

		}
		if err == nil {
			err = o.Commit()
		} else {
			err = o.Rollback()
		}
	}

	return err
}

//权限组所拥有的权限
func RuleList(GroupId int64) []*ResutlRule {
	list, _ := MenuList()
	rules, _ := GetAuthByGroupId(GroupId)
	return RuleTree(list, rules)
}

//权限树
func RuleTree(list []*Menu, rules []string) []*ResutlRule {
	result := make([]*ResutlRule, 0)
	//顶级节点
	for _, item := range list {
		if item.Fid == 0 {
			tmp := ResutlRule{
				Id:       item.Id,
				Title:    item.Name,
				Key:      item.Url,
				Expand:   true,
				Checked:  false,
				Children: []*ResutlRule{},
			}
			result = append(result, &tmp)
		}
	}
	//子节点
	for _, item := range result {
		GetTreeNode(item.Id, item, list, rules)
	}
	return result
}

func GetTreeNode(pId int64, treeNode *ResutlRule, list []*Menu, rules []string) {
	for i := 0; i < len(list); i++ {
		if list[i].Fid == pId {
			check := false
			for _, item := range rules {
				if item == list[i].Url {
					check = true
				}
			}
			child := ResutlRule{
				Id:       list[i].Id,
				Title:    list[i].Name,
				Key:      list[i].Url,
				Expand:   true,
				Checked:  check,
				Children: []*ResutlRule{},
			}
			treeNode.Children = append(treeNode.Children, &child)
			GetTreeNode(list[i].Id, &child, list, rules)
		}
	}
}
